<?php
/**
 * Created by Zhy
 * User: Zhy
 * Date: 2020/12/1
 * Time: 10:13
 */

namespace app\api\controller;

require_once(EXTEND_PATH . 'Paypal/autoload.php');

// 鉴权
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
// 付款
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use think\Db;
// 退款
use PayPal\Api\Refund;
use PayPal\Api\Sale;

class Paypal extends Base
{
    // 编号
    public $clientId = 'AU4_5qnsQhiWLmIx8ZJBUy9X7md8cBd8a7b7KPKdbjrPpUtEEm9uByTTS2KL1ImYksm_a4qA3Rw-XIBU';
    
    // 秘钥
    public $clientSecret = 'EBdCzCeqEclxKFNux5hJP-PdkcR0vGjKczjTpvWK63qCeXCH54W3Dw-7cOqhC_koX5waf1q2H_Wxb2WI';
    
    public $Paypal;
    
    public function __construct()
    {
        $this->Paypal = new ApiContext(new OAuthTokenCredential($this->clientId, $this->clientSecret));
    }
    
    /**
     * 选择付款方式，更新订单
     * @return \think\response\Json
     */
    public function updateOrder(){
        $order_id = input('order_id');
        $order = Db::table('up_goods_order')
            ->where('order_id', $order_id)
            ->field('order_pay_price')
            ->find();
        $result = exchange('USD');
        if($result['status'] == 200){
            $order_USD_price = $result['msg'] * $order['order_pay_price']; // 美元价格
            $res = Db::table('up_goods_order')
                ->where('order_id', $order_id)
                ->update([
                    'order_pay_type' => 5,
                    'order_updatetime' => date('Y-m-d H:i:s'),
                    'order_USD_price' => $order_USD_price
                ]);
            if($res){
                $order_new = Db::table('up_goods_order')
                    ->join('up_goods', 'goods_id = order_goods_id', 'LEFT')
                    ->join('up_yue', 'order_yue_id = yue_id', 'LEFT')
                    ->where('order_id', $order_id)
                    ->field('order_number, order_USD_price, goods_name, yue_title, order_type')
                    ->find();
                if($order_new['order_type'] == 4){
                    $order_new['goods_name'] = $order_new['yue_title'];
                }
                return json(['status' => 200, 'msg' => $order_new]);
            }else{
                return json(['status' => 0, 'msg' => false]);
            }
        }else{
            return json(['status' => 0, 'msg' => $result['msg']]);
        }
    }
    
    /**
     * 前端付款成功调用
     * @return \think\response\Json
     */
    public function paySuccessApi(){
        $order_number = input('order_number'); // 订单编号
        $return_id = input('return_id'); // 退款ID
        $order = Db::table('up_goods_order')
            ->where('order_number', $order_number)
            ->field('order_id, order_num, order_goods_id, order_buy_user_id, order_sail_user_id, 
                    order_type, order_yue_id, order_spec_id, order_status')
            ->find();
    
        if($order['order_status'] == 1){
            Db::startTrans();
            try{
                // 修改订单状态
                Db::table('up_goods_order')
                    ->where('order_id', $order['order_id'])
                    ->update([
                        'order_status' => 2,
                        'order_pay_time' => date('Y-m-d H:i:s'),
                        'order_pay_date' => date('Y-m-d'),
                        'order_return_number' => $return_id
                    ]);
            
                // 约稿订单
                if($order['order_type'] == 4){
                    Db::table('up_yue')->where('yue_id', $order['order_yue_id'])->setField('yue_status', 2);
                }
            
                // 除了押金订单，其他的需要给画师发个信息
                if($order['order_type'] != 5){
                    $notice = [
                        'notice_title' => '您有一个订单已付款',
                        'notice_content' => '您有一个订单已付款',
                        'notice_user' => ',' . $order['order_sail_user_id'] . ',',
                        'notice_type' => 5,
                        'notice_order_id' => $order['order_id'],
                        'notice_read_user' => ',0,',
                        'notice_del_user' => ',0,',
                        'notice_time' => date('Y-m-d H:i:s')
                    ];
                    Db::table('up_notice')->insert($notice);
                }
                
                Db::commit();
                return json(['status' => 200, 'msg' => 'success']);
            }catch(\Exception $e){
                Db::rollback();//回滚
                return json(['status' => 200, 'msg' => 'error']);
            }
        }else{
            return json(['status' => 200, 'msg' => 'success']);
        }
    }
    
    /**
     * 支付
     * @return null|string
     */
    public function payPal(){
        $payer = new Payer();
        $payer->setPaymentMethod('paypal');
    
        $item1 = new Item();
        $item1->setName('Ground Coffee 40 oz')
            ->setCurrency('USD')
            ->setQuantity(1)
            ->setSku("123123") // Similar to `item_number` in Classic API
            ->setPrice(7.5);
    
        $item2 = new Item();
        $item2->setName('Granola bars')
            ->setCurrency('USD')
            ->setQuantity(5)
            ->setSku("321321") // Similar to `item_number` in Classic API
            ->setPrice(2);
    
        $itemList = new ItemList();
        $itemList->setItems(array($item1, $item2));
    
        // 费用详情
        $details = new Details();
        $details->setShipping(1.2)
            ->setTax(1.3)
            ->setSubtotal(17.50);
    
        // 费用
        $amount = new Amount();
        $amount->setCurrency("USD")
            ->setTotal(20)
            ->setDetails($details);
    
        // 订单ID和支付描述
        $transaction = new Transaction();
        $transaction->setAmount($amount)
            ->setItemList($itemList)
            ->setDescription('订单支付')
            ->setInvoiceNumber(uniqid());
    
        // 支付成功回调、支付取消回调
        $redirectUrls = new RedirectUrls();
        $redirectUrls->setReturnUrl('http://yue.xuanwumobile.com/api/Paypal/callBack')
            ->setCancelUrl('http://yue.xuanwumobile.com/api/Paypal/cancelPay');
    
        $payment = new Payment();
        $payment->setIntent('sale')
            ->setPayer($payer)
            ->setRedirectUrls($redirectUrls)
            ->setTransactions(array($transaction));
    
//        $request = clone $payment;
        
        try{
            $payment->create($this->Paypal);
            $approvalUrl = $payment->getApprovalLink();
            return $approvalUrl;
        }catch(\PayPal\Exception\PayPalConnectionException $ex){
            return $ex->getData();
        }
//        return $payment;
    }
    
    /**
     * 回调参数打印
     */
    public function returnData($data = ''){
        $data = input('');
        $file_name = ROOT_PATH . '/public/file/' . date('Ymd', time()) . '.txt';
        if (is_array($data)) {
            $data_str = json_encode($data, true);
        } else {
            $data_str = $data;
        }
        file_put_contents($file_name, $data_str . "\r\n\r\n", FILE_APPEND);
    }
    
    /**
     * 回调参数打印
     */
    public function callBack(){
        $params = $_GET;
        $this->returnData($params);
        
        $paymentId = $_GET['paymentId'];
        $payment = Payment::get($paymentId, $this->Paypal);
        
        $payerId = $_GET['PayerID'];
        $execution = new PaymentExecution();
        $execution->setPayerId($payerId);
        try{
            $result = $payment->execute($execution, $this->Paypal);
            return json(['status' => 200, 'msg' => $result]);
        }catch(\Exception $e){
            return json(['status' => 0, 'msg' => $e->getMessage()]);
        }
        // 官方文档需要判断success，但实际服务器并没有返次参数
//        if(isset($_GET['success']) && $_GET['success'] == 'true'){
//            $paymentId = $_GET['paymentId'];
//
//            $payment = Payment::get($paymentId, $this->Paypal);
//            $payerId = $_GET['PayerID'];
//
//            $execution = new PaymentExecution();
//            $execution->setPayerId($payerId);
//            try{
//                $result = $payment->execute($execution, $this->Paypal);
//                return json(['status' => 200, 'msg' => $result]);
//            }catch(\Exception $e){
//                return json(['status' => 0, 'msg' => $e->getMessage()]);
//            }
//        }else{
//            return json(['status' => 0, 'msg' => '系统错误']);
//        }
    }
    
    /**
     * 取消支付回调
     * @return \think\response\Json
     */
    public function cancelPay(){
        return json(['status' => 0, 'msg' => '取消付款成功']);
    }
    
    /**
     * paypal退款
     * @param $return_price
     * @param $return_id
     * @return array
     */
    public function returnPay($return_price, $return_id){
        $this->Paypal->setConfig([
            'mode' => 'sandbox'
        ]);
        $amt = new Amount();
        $amt->setCurrency('USD')->setTotal($return_price);
    
        $refund = new Refund();
        $refund->setAmount($amt);
    
        // 根据$return_id(paymentId)获取sale id
        $payment = Payment::get($return_id, $this->Paypal);
        $transactions = $payment->getTransactions();
        $resources = $transactions[0]->getRelatedResources();//This DOESN'T work for PayPal transactions.
    
        $sale = $resources[0]->getSale();
        $saleID = $sale->getId();
    
        $sale = new Sale();
        $sale->setId($saleID);
    
        try{
            $refundedSale = $sale->refundSale($refund, $this->Paypal);
            return ['status' => 200, 'msg' => true];
        }catch(\Paypal\Exception\PayPalConnectionException $ex){
            return ['status' => 0, 'msg' => $ex->getMessage()];
        }catch(\Exception $e){
            return ['status' => 0, 'msg' => $e->getMessage()];
        }
    }
}